﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Softyum.Common.Drawing;
using Softyum.Common.OS;
using Softyum.ForexAgent.Config;

namespace Softyum.ForexAgent.Forms
{
    public partial class PopupMessageForm : Form
    {
        public Boolean UseAutoCloseTimer { get; set; }
        public Int32 AutoCloseTimer { get; set; }
        //
        public String Title { get; set; }
        public Font TitleFont { get; set; }
        public Color TitleColor { get; set; }
        public Point TitlePos { get; set; }
        public Point TextPos { get; set; }
        /// <summary>
        /// 边框
        /// </summary>
        public Int32 Radius { get; set; }
        public Int32 BorderWidth { get; set; }
        public Color BorderColor { get; set; }
        /// <summary>
        /// 窗体渐变色
        /// </summary>
        public Boolean UseLinearGradient { get; set; }
        public Color LinearGradientStart { get; set; }
        public Color LinearGradientEnd { get; set; }
        public Int32 LinearGradientAngle { get; set; }

        //
        private PopupWindowSettings _settings = Program.ConfigManager.PopupWindowSettings; 

        //
        private Size _titlePartSize;

        /// <summary>
        /// Timer for show the form
        /// </summary>
        private Timer showTimer;
        private object showTimerSyncRoot = new Object();

        /// <summary>
        /// Ctor
        /// </summary>
        public PopupMessageForm() : this(true)
        {
        }
        
        public PopupMessageForm(Boolean autoClose)
        {
            //
            UseAutoCloseTimer = autoClose;
            //
            InitializeComponent();
        }

        #region Publics
        public void Show(string title, string text)
        {
            // Set Text for showing
            this.Text = text;
            this.Title = title;

            // Make visible
            this.Visible = true;

            // Show timer
            if (UseAutoCloseTimer)
                StartAutoCloseTimer();
        }
        #endregion

        #region Form Events
        private void PopupMessageForm_Load(object sender, EventArgs e)
        {
            // Binding
            this.DataBindings.Add(new Binding("TitlePos", _settings, PopupWindowSettings.TITLE_POS));
            this.DataBindings.Add(new Binding("TextPos", _settings, PopupWindowSettings.TEXT_POS));
            this.DataBindings.Add(new Binding("MinimumSize", _settings, PopupWindowSettings.MINIMUM_SIZE));
            this.DataBindings.Add(new Binding("ForeColor", _settings, PopupWindowSettings.FORE_COLOR));
            this.DataBindings.Add(new Binding("Font", _settings, PopupWindowSettings.FONT));
            this.DataBindings.Add(new Binding("TitleColor", _settings, PopupWindowSettings.TITLE_COLOR));
            this.DataBindings.Add(new Binding("TitleFont", _settings, PopupWindowSettings.TITLE_FONT));
            this.DataBindings.Add(new Binding("AutoCloseTimer", _settings, PopupWindowSettings.AUTO_CLOSE_TIMER));
            this.DataBindings.Add(new Binding("Radius", _settings, PopupWindowSettings.RADIUS));
            this.DataBindings.Add(new Binding("BorderWidth", _settings, PopupWindowSettings.BORDER_WIDTH));
            this.DataBindings.Add(new Binding("BorderColor", _settings, PopupWindowSettings.BORDER_COLOR));
            //
            this.DataBindings.Add(new Binding("UseLinearGradient", _settings, PopupWindowSettings.USE_LINEAR_GRADIENT));
            this.DataBindings.Add(new Binding("LinearGradientStart", _settings, PopupWindowSettings.LINEAR_GRADIENT_START));
            this.DataBindings.Add(new Binding("LinearGradientEnd", _settings, PopupWindowSettings.LINEAR_GRADIENT_END));
            this.DataBindings.Add(new Binding("LinearGradientAngle", _settings, PopupWindowSettings.LINEAR_GRADIENT_ANGLE));

            // 
            Size titleSize = TextRenderer.MeasureText(Title, TitleFont,
                MinimumSize, TextFormatFlags.WordBreak);
            _titlePartSize = new Size(titleSize.Width + TitlePos.X, titleSize.Height + TitlePos.Y);

            // Size
            Size textSize = TextRenderer.MeasureText(Text, this.Font,
                MinimumSize, TextFormatFlags.WordBreak);
            Size textPartSize = new Size(textSize.Width + TextPos.X, textSize.Height + TextPos.Y);

            // add title ctr height
            this.Size = Size.Add(_titlePartSize, textPartSize);

            // Location
            Screen screen = Screen.FromControl(this);
            int y = screen.WorkingArea.Height - this.Height;
            int x = screen.WorkingArea.Width - this.Width;
            this.Location = new Point(x, y);
        }
        #endregion

        #region Overrides
        protected override void OnPaint(PaintEventArgs e)
        {
            // draw title
            TextRenderer.DrawText(e.Graphics, Title, TitleFont, TitlePos, TitleColor);
            // draw text
            TextRenderer.DrawText(e.Graphics, Text, Font, new Point(TextPos.X, _titlePartSize.Height + TextPos.Y), ForeColor);
            // base.OnPaint(e);
            GraphicsPath path = 
                RoundedRectangle.Create(e.ClipRectangle, Radius);

            //e.Graphics.SetClip(path, CombineMode.Replace);
            this.Region = new Region(path);
        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            // 窗体
            GraphicsPath path = 
                RoundedRectangle.Create(e.ClipRectangle, Radius);

            if (UseLinearGradient)
            {
                using (LinearGradientBrush brush = 
                    new LinearGradientBrush(e.ClipRectangle, 
                        LinearGradientStart, 
                        LinearGradientEnd, 
                        LinearGradientAngle))
                {
                    e.Graphics.FillPath(brush, path);
                }
            }

            // 边框
            using (Pen p = new Pen(BorderColor, BorderWidth))
            {
                e.Graphics.DrawPath(p, path);
            }
        }

        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams baseParams = base.CreateParams;

                // WS_EX_NOACTIVATE = 0x08000000,
                // WS_EX_TOOLWINDOW = 0x00000080,
                baseParams.ExStyle |= (int)(0x08000000 | 0x00000080);

                return baseParams;
            }
        }

        protected override bool ShowWithoutActivation
        {
            get { return true; }
        }
        #endregion

        #region Menu & Button Events
        private void btnClose_Click(object sender, EventArgs e)
        {
            if (showTimer != null)
            {
                lock (showTimer)
                {
                    // we should not close the timer first
                    showTimer.Stop();
                    // then close the window
                    this.Close();
                }
            }
        }

        private void btnClose_MouseEnter(object sender, EventArgs e)
        {
            /*
            if (this.showTimer != null)
            {
                using (showTimer)
                {
                    showTimer.Stop();
                }
                showTimer = null;
            }
            */
        }

        private void btnClose_MouseLeave(object sender, EventArgs e)
        {
            /** StartShowTimer(); */
        }


        #endregion

        #region Show Timer
        private void StartAutoCloseTimer()
        {
            lock (showTimerSyncRoot)
            {
                if (showTimer != null)
                {
                    throw new Exception("ShowTimer aready started");
                }
                showTimer = new Timer();
                showTimer.Interval = this.AutoCloseTimer;
                showTimer.Tick += new EventHandler(showTimer_Tick);
                showTimer.Start();
            }
        }

        private void StopShowTimer()
        {
            lock (showTimerSyncRoot)
            {
                if (showTimer != null)
                {
                    throw new Exception("ShowTimer not started");
                }
                using (showTimer)
                {
                    showTimer.Stop();
                    showTimer = null;
                }
            }
        }

        void showTimer_Tick(object sender, EventArgs e)
        {
            lock (showTimerSyncRoot)
            {
                using (showTimer)
                {
                    showTimer.Stop();
                    showTimer = null;
                } 
            }
            AnimateWindow.Hide(this, 2000);
            Close();
        }
        #endregion

    }
}
